package com.mathlearning.auth.service;

import com.mathlearning.auth.common.BusinessException;
import com.mathlearning.auth.dto.learning.*;
import com.mathlearning.auth.entity.*;
import com.mathlearning.auth.repository.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class LearningService {
    
    @Autowired
    private LearningCategoryRepository categoryRepository;
    
    @Autowired
    private LearningCourseRepository courseRepository;
    
    @Autowired
    private LearningChapterRepository chapterRepository;
    
    @Autowired
    private LearningVideoRepository videoRepository;
    
    @Autowired
    private LearningProgressRepository progressRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private CoursePurchaseRepository coursePurchaseRepository;
    
    /**
     * 获取课程分类列表
     */
    public CategoryListResponse getCategories() {
        List<LearningCategory> categories = categoryRepository.findAllByOrderBySortOrderAsc();
        
        List<CategoryListResponse.CategoryItem> items = categories.stream()
            .map(category -> {
                Long count = categoryRepository.countPublishedCourses(category.getId());
                return CategoryListResponse.CategoryItem.builder()
                    .id(category.getId())
                    .name(category.getName())
                    .icon(category.getIcon())
                    .count(count)
                    .build();
            })
            .collect(Collectors.toList());
        
        return CategoryListResponse.builder()
            .total(items.size())
            .categories(items)
            .build();
    }
    
    /**
     * 获取课程列表
     */
    public CourseListResponse getCourseList(CourseQueryRequest request, Long userId) {
        // 构建分页参数
        Pageable pageable = buildPageable(request);
        
        // 查询课程列表
        Page<LearningCourse> coursePage;
        
        if (request.getCategoryId() != null && request.getDifficulty() != null) {
            // 按分类和难度筛选
            coursePage = courseRepository.findByCategoryIdAndDifficultyAndStatus(
                request.getCategoryId(), request.getDifficulty(), "published", pageable);
        } else if (request.getCategoryId() != null) {
            // 按分类筛选
            coursePage = courseRepository.findByCategoryIdAndStatus(
                request.getCategoryId(), "published", pageable);
        } else if (request.getDifficulty() != null) {
            // 按难度筛选
            coursePage = courseRepository.findByDifficultyAndStatus(
                request.getDifficulty(), "published", pageable);
        } else {
            // 查询所有课程（包括draft状态，用于测试）
            coursePage = courseRepository.findAll(pageable);
        }
        
        // 转换为DTO
        List<CourseListResponse.CourseItem> courseItems = coursePage.getContent().stream()
            .map(course -> convertToCourseItem(course, userId))
            .collect(Collectors.toList());
        
        return CourseListResponse.builder()
            .list(courseItems)
            .total(coursePage.getTotalElements())
            .page(request.getPage())
            .pageSize(request.getPageSize())
            .build();
    }
    
    /**
     * 获取课程详情
     */
    public CourseDetailResponse getCourseDetail(Long courseId, Long userId) {
        // 查询课程
        LearningCourse course = courseRepository.findById(courseId)
            .orElseThrow(() -> new BusinessException("课程不存在"));
        
        // 查询分类名称
        String categoryName = categoryRepository.findById(course.getCategoryId())
            .map(LearningCategory::getName)
            .orElse("");
        
        // 查询讲师信息
        InstructorInfo instructor = getInstructorInfo(course.getInstructorId());
        
        // 查询章节列表
        List<LearningChapter> chapters = chapterRepository.findByCourseIdOrderBySortOrderAsc(courseId);
        
        // 查询用户学习进度
        Map<Long, LearningProgress> progressMap = progressRepository.findByUserIdAndCourseId(userId, courseId)
            .stream()
            .collect(Collectors.toMap(LearningProgress::getVideoId, p -> p));
        
        // 构建章节信息
        List<ChapterInfo> chapterInfos = chapters.stream()
            .map(chapter -> {
                // 查询该章节的视频列表
                List<LearningVideo> videos = videoRepository.findByChapterIdOrderBySortOrderAsc(chapter.getId());
                
                // 构建视频信息
                List<VideoSimpleInfo> videoInfos = videos.stream()
                    .map(video -> {
                        LearningProgress progress = progressMap.get(video.getId());
                        Integer progressPercent = 0;
                        Boolean completed = false;
                        
                        if (progress != null) {
                            completed = progress.getCompleted();
                            if (progress.getTotalDuration() > 0) {
                                progressPercent = (int) ((progress.getWatchDuration() * 100.0) / progress.getTotalDuration());
                            }
                        }
                        
                        return VideoSimpleInfo.builder()
                            .id(video.getId())
                            .title(video.getTitle())
                            .duration(video.getDuration())
                            .thumbnail(video.getThumbnail())
                            .completed(completed)
                            .progress(progressPercent)
                            .build();
                    })
                    .collect(Collectors.toList());
                
                // 统计已完成视频数量
                int completedCount = (int) videoInfos.stream()
                    .filter(VideoSimpleInfo::getCompleted)
                    .count();
                
                return ChapterInfo.builder()
                    .id(chapter.getId())
                    .title(chapter.getTitle())
                    .description(chapter.getDescription())
                    .videoCount(videos.size())
                    .completedCount(completedCount)
                    .videos(videoInfos)
                    .build();
            })
            .collect(Collectors.toList());
        
        // 计算课程总体进度
        Integer courseProgress = calculateCourseProgress(userId, courseId);
        
        return CourseDetailResponse.builder()
            .id(course.getId())
            .categoryId(course.getCategoryId())
            .categoryName(categoryName)
            .title(course.getTitle())
            .description(course.getDescription())
            .cover(course.getCover())
            .difficulty(course.getDifficulty())
            .videoCount(course.getVideoCount())
            .studentCount(course.getStudentCount())
            .instructor(instructor)
            .progress(courseProgress)
            .createdAt(course.getCreatedAt())
            .chapters(chapterInfos)
            .build();
    }
    
    /**
     * 获取视频详情
     */
    public VideoDetailResponse getVideoDetail(Long videoId, Long userId) {
        // 查询视频
        LearningVideo video = videoRepository.findById(videoId)
            .orElseThrow(() -> new BusinessException("视频不存在"));
        
        // 查询章节
        LearningChapter chapter = chapterRepository.findById(video.getChapterId())
            .orElseThrow(() -> new BusinessException("章节不存在"));
        
        // 查询课程
        LearningCourse course = courseRepository.findById(video.getCourseId())
            .orElseThrow(() -> new BusinessException("课程不存在"));
        
        // 查询讲师信息
        InstructorInfo instructor = getInstructorInfo(course.getInstructorId());
        
        // 查询用户学习进度
        VideoProgressInfo progressInfo = null;
        Optional<LearningProgress> progressOpt = progressRepository.findByUserIdAndVideoId(userId, videoId);
        if (progressOpt.isPresent()) {
            LearningProgress progress = progressOpt.get();
            progressInfo = VideoProgressInfo.builder()
                .watchDuration(progress.getWatchDuration())
                .completed(progress.getCompleted())
                .lastWatchTime(progress.getLastWatchTime())
                .build();
        }
        
        // 查询前一个和下一个视频
        NextVideoInfo prevVideo = findPreviousVideo(video);
        NextVideoInfo nextVideo = findNextVideo(video);
        
        // 检查用户是否购买了课程
        boolean hasPurchased = false;
        try {
            hasPurchased = coursePurchaseRepository
                .existsByUserIdAndCourseIdAndStatus(userId, video.getCourseId(), "active");
        } catch (Exception e) {
            log.warn("检查课程购买状态失败: userId={}, courseId={}", userId, video.getCourseId(), e);
        }
        
        // 检查用户是否是会员
        boolean isVip = false;
        try {
            User user = userRepository.findById(userId).orElse(null);
            if (user != null) {
                isVip = user.getIsVip() != null && user.getIsVip() == 1 && 
                    (user.getVipExpireTime() == null || user.getVipExpireTime().isAfter(java.time.LocalDateTime.now()));
            }
        } catch (Exception e) {
            log.warn("检查会员状态失败: userId={}", userId, e);
        }
        
        return VideoDetailResponse.builder()
            .id(video.getId())
            .chapterId(chapter.getId())
            .chapterTitle(chapter.getTitle())
            .courseId(course.getId())
            .courseTitle(course.getTitle())
            .title(video.getTitle())
            .description(video.getDescription())
            .videoUrl(video.getVideoUrl())
            .duration(video.getDuration())
            .thumbnail(video.getThumbnail())
            .viewCount(video.getViewCount())
            .instructor(instructor)
            .progress(progressInfo)
            .nextVideo(nextVideo)
            .prevVideo(prevVideo)
            // 权限相关字段
            .accessType(video.getAccessType())
            .previewDuration(video.getPreviewDuration())
            .hasPurchased(hasPurchased)
            .isVip(isVip)
            .build();
    }
    
    /**
     * 记录学习进度
     */
    @Transactional
    public RecordProgressResponse recordProgress(RecordProgressRequest request, Long userId) {
        // 查询视频
        LearningVideo video = videoRepository.findById(request.getVideoId())
            .orElseThrow(() -> new BusinessException("视频不存在"));
        
        // 查询或创建进度记录
        LearningProgress progress = progressRepository.findByUserIdAndVideoId(userId, request.getVideoId())
            .orElse(new LearningProgress());
        
        boolean isFirstWatch = (progress.getId() == null);
        
        progress.setUserId(userId);
        progress.setCourseId(video.getCourseId());
        progress.setVideoId(request.getVideoId());
        progress.setWatchDuration(request.getWatchDuration());
        progress.setTotalDuration(request.getTotalDuration());
        
        // 计算完成状态（观看进度 >= 90%）
        double watchPercentage = (double) request.getWatchDuration() / request.getTotalDuration();
        if (watchPercentage >= 0.9) {
            progress.setCompleted(true);
        }
        
        progress.setLastWatchTime(java.time.LocalDateTime.now());
        
        progressRepository.save(progress);
        
        // 如果是首次观看，增加视频播放次数
        if (isFirstWatch) {
            videoRepository.incrementViewCount(request.getVideoId());
            
            // 检查用户是否首次学习该课程
            if (!progressRepository.existsByUserIdAndCourseId(userId, video.getCourseId())) {
                // 增加课程学习人数
                courseRepository.incrementStudentCount(video.getCourseId());
            }
        }
        
        // 计算进度百分比
        int progressPercent = (int) ((request.getWatchDuration() * 100.0) / request.getTotalDuration());
        
        return RecordProgressResponse.builder()
            .progress(progressPercent)
            .completed(progress.getCompleted())
            .build();
    }
    
    /**
     * 获取用户课程学习进度
     */
    public CourseProgressResponse getCourseProgress(Long courseId, Long userId) {
        // 查询课程总视频数
        Long totalVideos = videoRepository.countByCourseId(courseId);
        
        if (totalVideos == 0) {
            return CourseProgressResponse.builder()
                .courseId(courseId)
                .totalVideos(0)
                .completedVideos(0)
                .progress(0)
                .build();
        }
        
        // 查询用户完成的视频数
        Long completedVideos = progressRepository.countCompletedVideos(userId, courseId);
        
        // 计算进度
        int progress = (int) ((completedVideos * 100.0) / totalVideos);
        
        // 查询最后观看的视频
        CourseProgressResponse.LastWatchVideoInfo lastWatchVideo = null;
        List<LearningProgress> lastWatchList = progressRepository.findLastWatchedVideo(userId, courseId);
        if (!lastWatchList.isEmpty()) {
            LearningProgress lastProgress = lastWatchList.get(0);
            LearningVideo video = videoRepository.findById(lastProgress.getVideoId()).orElse(null);
            if (video != null) {
                LearningChapter chapter = chapterRepository.findById(video.getChapterId()).orElse(null);
                lastWatchVideo = CourseProgressResponse.LastWatchVideoInfo.builder()
                    .id(video.getId())
                    .title(video.getTitle())
                    .chapterTitle(chapter != null ? chapter.getTitle() : "")
                    .build();
            }
        }
        
        // 查询继续观看的视频（第一个未完成的视频）
        CourseProgressResponse.ContinueWatchVideoInfo continueWatchVideo = null;
        List<LearningProgress> incompleteList = progressRepository.findFirstIncompleteVideo(userId, courseId);
        if (!incompleteList.isEmpty()) {
            LearningProgress incompleteProgress = incompleteList.get(0);
            LearningVideo video = videoRepository.findById(incompleteProgress.getVideoId()).orElse(null);
            if (video != null) {
                continueWatchVideo = CourseProgressResponse.ContinueWatchVideoInfo.builder()
                    .id(video.getId())
                    .title(video.getTitle())
                    .build();
            }
        }
        
        return CourseProgressResponse.builder()
            .courseId(courseId)
            .totalVideos(totalVideos.intValue())
            .completedVideos(completedVideos.intValue())
            .progress(progress)
            .lastWatchVideo(lastWatchVideo)
            .continueWatchVideo(continueWatchVideo)
            .build();
    }
    
    // ==================== 私有辅助方法 ====================
    
    /**
     * 构建分页参数
     */
    private Pageable buildPageable(CourseQueryRequest request) {
        Sort sort;
        
        String sortBy = request.getSortBy();
        if (sortBy == null) {
            sortBy = "latest";
        }
        
        switch (sortBy) {
            case "popular":
                // 按学习人数倒序
                sort = Sort.by(Sort.Direction.DESC, "studentCount");
                break;
            case "recommended":
                // 按排序顺序和创建时间
                sort = Sort.by(Sort.Direction.ASC, "sortOrder")
                    .and(Sort.by(Sort.Direction.DESC, "createdAt"));
                break;
            case "latest":
            default:
                // 按创建时间倒序
                sort = Sort.by(Sort.Direction.DESC, "createdAt");
                break;
        }
        
        return PageRequest.of(request.getPage() - 1, request.getPageSize(), sort);
    }
    
    /**
     * 转换为课程列表项
     */
    private CourseListResponse.CourseItem convertToCourseItem(LearningCourse course, Long userId) {
        // 查询分类名称
        String categoryName = categoryRepository.findById(course.getCategoryId())
            .map(LearningCategory::getName)
            .orElse("");
        
        // 查询讲师信息
        InstructorInfo instructor = getInstructorInfo(course.getInstructorId());
        
        // 查询用户学习进度
        Integer progress = calculateCourseProgress(userId, course.getId());
        
        return CourseListResponse.CourseItem.builder()
            .id(course.getId())
            .categoryId(course.getCategoryId())
            .categoryName(categoryName != null ? categoryName : "")
            .title(course.getTitle() != null ? course.getTitle() : "")
            .description(course.getDescription() != null ? course.getDescription() : "")
            .cover(course.getCover() != null ? course.getCover() : "")
            .difficulty(course.getDifficulty() != null ? course.getDifficulty() : "beginner")
            .videoCount(course.getVideoCount() != null ? course.getVideoCount() : 0)
            .studentCount(course.getStudentCount() != null ? course.getStudentCount() : 0)
            .instructor(instructor)
            .progress(progress != null ? progress : 0)
            .createdAt(course.getCreatedAt())
            .build();
    }
    
    /**
     * 获取讲师信息
     */
    private InstructorInfo getInstructorInfo(Long instructorId) {
        if (instructorId == null) {
            return InstructorInfo.builder()
                .id(null)
                .name("未知讲师")
                .build();
        }
        
        return userRepository.findById(instructorId)
            .map(user -> InstructorInfo.builder()
                .id(user.getId())
                .name(user.getNickname() != null ? user.getNickname() : 
                      (user.getPhone() != null ? user.getPhone() : "未知讲师"))
                .avatar(user.getAvatar() != null ? user.getAvatar() : "")
                .bio(user.getBio() != null ? user.getBio() : "")
                .build())
            .orElse(InstructorInfo.builder()
                .id(instructorId)
                .name("未知讲师")
                .build());
    }
    
    /**
     * 计算用户课程学习进度
     */
    private Integer calculateCourseProgress(Long userId, Long courseId) {
        // 查询课程总视频数
        Long totalVideos = videoRepository.countByCourseId(courseId);
        if (totalVideos == 0) {
            return 0;
        }
        
        // 查询用户完成的视频数
        Long completedVideos = progressRepository.countCompletedVideos(userId, courseId);
        
        // 计算进度
        return (int) ((completedVideos * 100.0) / totalVideos);
    }
    
    /**
     * 查找前一个视频
     */
    private NextVideoInfo findPreviousVideo(LearningVideo currentVideo) {
        Optional<LearningVideo> prevOpt = videoRepository.findPreviousVideo(
            currentVideo.getCourseId(),
            currentVideo.getChapterId(),
            currentVideo.getSortOrder()
        );
        
        return prevOpt.map(video -> NextVideoInfo.builder()
            .id(video.getId())
            .title(video.getTitle())
            .build()).orElse(null);
    }
    
    /**
     * 查找下一个视频
     */
    private NextVideoInfo findNextVideo(LearningVideo currentVideo) {
        Optional<LearningVideo> nextOpt = videoRepository.findNextVideo(
            currentVideo.getCourseId(),
            currentVideo.getChapterId(),
            currentVideo.getSortOrder()
        );
        
        return nextOpt.map(video -> NextVideoInfo.builder()
            .id(video.getId())
            .title(video.getTitle())
            .build()).orElse(null);
    }
}



